package com.ubxtech.rocketmq.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.ubxtech.rocketmq.core.RocketExtTemplate;
import com.ubxtech.rocketmq.properties.RocketMqConfigProperties;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.RocketMQMessageConverter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.messaging.converter.CompositeMessageConverter;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.MessageConverter;

import java.util.List;

/**
 * https://blog.csdn.net/qq_43985303/article/details/130980933
 * https://zhuanlan.zhihu.com/p/623045265?utm_id=0
 * @author Victor.Xiao
 * @since 2023-11-28 19:55
 **/
@Configuration
@EnableConfigurationProperties(RocketMqConfigProperties.class)
public class RocketMqConfig {

    /**
     * 环境隔离配置
     */
    @Bean
    @ConditionalOnProperty(name="ubxtech.rocketmq.envIsolationFlag", havingValue="1" ,matchIfMissing = true)
    public IsolationConfig environmentSetup(RocketMqConfigProperties rocketMqConfigProperties){
        return new IsolationConfig(rocketMqConfigProperties);
    }

    /**
     * 注入增强的RocketMQEnhanceTemplate,生产者环境隔离在RocketExtTemplate内部判断
     * RocketMQTemplate一定要配置rocketmq.producer.group
     */
    @Bean
    @ConditionalOnProperty(name="ubxtech.rocketmq.envIsolationFlag", havingValue="1" ,matchIfMissing = true)
    public RocketExtTemplate rocketExtTemplate(RocketMQTemplate rocketMQTemplate,RocketMqConfigProperties rocketMqConfigProperties){
        return new RocketExtTemplate(rocketMQTemplate,rocketMqConfigProperties);
    }

    /**
     * 解决RocketMQ Jackson不支持Java时间类型配置
     * 源码参考：{@link org.apache.rocketmq.spring.autoconfigure.MessageConverterConfiguration}
     */
    @Bean
    @Primary
    public RocketMQMessageConverter enhanceRocketMQMessageConverter(){
        RocketMQMessageConverter converter = new RocketMQMessageConverter();
        CompositeMessageConverter compositeMessageConverter = (CompositeMessageConverter) converter.getMessageConverter();
        List<MessageConverter> messageConverterList = compositeMessageConverter.getConverters();
        for (MessageConverter messageConverter : messageConverterList) {
            if(messageConverter instanceof MappingJackson2MessageConverter){
                MappingJackson2MessageConverter jackson2MessageConverter = (MappingJackson2MessageConverter) messageConverter;
                ObjectMapper objectMapper = jackson2MessageConverter.getObjectMapper();
                objectMapper.registerModules(new JavaTimeModule());
            }
        }
        return converter;
    }
}
